#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <sstream>
using std::istringstream;
using std::cout;
using std::endl;
using std::string;
using std::set;
using std::map;
using std::vector;
using std::ifstream;

class TextQuery{
public:
    TextQuery(int size)
    {
        _lines.reserve(size);
    }
    bool is_word(const string & word);
    void readFile(const string & filename);
    void query(const string & word);//

private:
    vector<string> _lines;//O(1) 
    map<string, set<int>> _wordNumbers;//单词所在行号
    map<string, int> _dict;//单词词频
};

bool TextQuery::is_word(const string & word){
    for(auto & ch : word){
        if(!isalpha(ch)){
            return false;
        }
    }
    return true;
}
void TextQuery::readFile(const string & filename){
    ifstream ifs(filename);
    string line;
    string word;
    int line_count = 1;
    while(getline(ifs,line)){
        _lines.push_back(line);
        istringstream iss(line);
        while(iss >> word){
            if(is_word(word)){
                _wordNumbers[word].insert(line_count); //记录行号
                _dict[word] += 1; //统计词频
            }
            word.clear();
        }
        line.clear();
        ++line_count;
    }
}


void TextQuery::query(const string & word){
    cout << word << " occurs " << _dict[word] << " times" << endl;
    for(auto & line_count:_wordNumbers[word]){ //遍历set
        cout << "(line " << line_count << ") " 
            << _lines[line_count -1] << '.' << endl; 
    }
}


void test(){
    TextQuery tq(200);
    tq.readFile("china_daily.txt");
    tq.query("The");
    tq.query("link");
}

int main()
{
    

    test ();
    return 0;
}

